home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Development Tools & Languages / Dylan Related / Marlais / Marlais 0.5.9-portable sources / number.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-15  |  16.4 KB  |  771 lines  |  [TEXT/ttxt]

  1. /*
  2.  
  3.    number.c
  4.  
  5.    This software is free software; you can redistribute it and/or
  6.    modify it under the terms of the GNU Library General Public
  7.    License as published by the Free Software Foundation; either
  8.    version 2 of the License, or (at your option) any later version.
  9.  
  10.    This software is distributed in the hope that it will be useful,
  11.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.    Library General Public License for more details.
  14.  
  15.    You should have received a copy of the GNU Library General Public
  16.    License along with this software; if not, write to the Free
  17.    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19.    Original copyright notice follows:
  20.  
  21.    Copyright, 1993, Brent Benson.  All Rights Reserved.
  22.    0.4 & 0.5 Revisions Copyright 1994, Joseph N. Wilson.  All Rights Reserved.
  23.  
  24.    Permission to use, copy, and modify this software and its
  25.    documentation is hereby granted only under the following terms and
  26.    conditions.  Both the above copyright notice and this permission
  27.    notice must appear in all copies of the software, derivative works
  28.    or modified version, and both notices must appear in supporting
  29.    documentation.  Users of this software agree to the terms and
  30.    conditions set forth in this notice.
  31.  
  32.  */
  33.  
  34. #include <math.h>
  35.  
  36. #include "number.h"
  37.  
  38. #include "prim.h"
  39. #include "values.h"
  40.  
  41. #ifdef BIG_INTEGERS
  42. #include "biginteger.h"
  43.  
  44. #define MAX_SMALL_INT ((1 << 29) - 1)
  45. #define MAX_SMALL_FACTOR (23170)
  46.  
  47. #define INT_ABS(i) (i < 0 ? -i : i)
  48.  
  49. #endif
  50.  
  51. #if defined(_CX_UX) || defined(MACOS) || defined(sgi) || defined(_HP_UX) \
  52. || defined(__SunOS_5__) || defined(__linux__)
  53. #define NO_DOUBLE_INT_ARITH
  54. #endif
  55.  
  56. #ifdef NO_DOUBLE_INT_ARITH
  57. static double anint (double x);
  58. static double aint (double x);
  59.  
  60. #endif
  61.  
  62. /* primitives */
  63.  
  64. static Object odd_p (Object n);
  65. static Object even_p (Object n);
  66. static Object int_zero_p (Object n);
  67. static Object double_zero_p (Object n);
  68. static Object int_positive_p (Object n);
  69. static Object double_positive_p (Object n);
  70. static Object int_negative_p (Object n);
  71. static Object double_negative_p (Object n);
  72. static Object integral_p (Object n);
  73. static Object int_to_double (Object n);
  74. static Object double_to_int (Object n);
  75. static Object int_negative (Object n);
  76. static Object double_negative (Object n);
  77. static Object int_inverse (Object n);
  78. static Object double_inverse (Object n);
  79. static Object binary_int_plus (Object n1, Object n2);
  80. static Object binary_int_minus (Object n1, Object n2);
  81. static Object binary_int_times (Object n1, Object n2);
  82. static Object binary_int_divide (Object n1, Object n2);
  83. static Object binary_double_plus (Object n1, Object n2);
  84. static Object binary_double_minus (Object n1, Object n2);
  85. static Object binary_double_times (Object n1, Object n2);
  86. static Object binary_double_divide (Object n1, Object n2);
  87. static Object binary_less_than (Object n1, Object n2);
  88. static Object int_sqrt (Object n);
  89. static Object double_sqrt (Object n);
  90. static Object int_abs (Object n);
  91. static Object double_abs (Object n);
  92. static Object int_quotient (Object n1, Object n2);
  93. static Object ash (Object n, Object count);
  94. static Object binary_logand (Object n1, Object n2);
  95. static Object binary_logior (Object n1, Object n2);
  96. static Object double_sin (Object n1);
  97. static Object double_cos (Object n1);
  98. static Object double_atan2 (Object n1, Object n2);
  99. static Object floor_func (Object d);
  100. static Object ceiling (Object d);
  101. static Object round (Object d);
  102. static Object truncate (Object d);
  103. static Object modulo (Object d1, Object d2);
  104. static Object modulo_double (Object d1, Object d2);
  105. static Object remainder_double (Object d1, Object d2);
  106. static Object remainder_int (Object i1, Object i2);
  107. static Object double_exp (Object d);
  108. static Object double_log (Object d);
  109. static Object floor_divide (Object d1, Object d2);
  110. static Object ceiling_divide (Object d1, Object d2);
  111. static Object round_divide (Object d1, Object d2);
  112. static Object truncate_divide (Object d1, Object d2);
  113. static Object int_truncate_divide (Object i1, Object i2);
  114. static struct primitive number_prims[] =
  115. {
  116.     {"%odd?", prim_1, odd_p},
  117.     {"%even?", prim_1, even_p},
  118.     {"%int-zero?", prim_1, int_zero_p},
  119.     {"%double-zero?", prim_1, double_zero_p},
  120.     {"%int-positive?", prim_1, int_positive_p},
  121.     {"%double-positive?", prim_1, double_positive_p},
  122.     {"%int-negative?", prim_1, int_negative_p},
  123.     {"%double-negative?", prim_1, double_negative_p},
  124.     {"%integral?", prim_1, integral_p},
  125.     {"%int-to-double", prim_1, int_to_double},
  126.     {"%double-to-int", prim_1, double_to_int},
  127.     {"%int-negative", prim_1, int_negative},
  128.     {"%double-negative", prim_1, double_negative},
  129.     {"%int-inverse", prim_1, int_inverse},
  130.     {"%double-inverse", prim_1, double_inverse},
  131.     {"%binary-int+", prim_2, binary_int_plus},
  132.     {"%binary-int-", prim_2, binary_int_minus},
  133.     {"%binary-int*", prim_2, binary_int_times},
  134.     {"%binary-int/", prim_2, binary_int_divide},
  135.     {"%binary-double+", prim_2, binary_double_plus},
  136.     {"%binary-double-", prim_2, binary_double_minus},
  137.     {"%binary-double*", prim_2, binary_double_times},
  138.     {"%binary-double/", prim_2, binary_double_divide},
  139.     {"%binary-less-than", prim_2, binary_less_than},
  140.     {"%int-sqrt", prim_1, int_sqrt},
  141.     {"%double-sqrt", prim_1, double_sqrt},
  142.     {"%int-abs", prim_1, int_abs},
  143.     {"%double-abs", prim_1, double_abs},
  144.     {"%quotient", prim_2, int_quotient},
  145.     {"%ash", prim_2, ash},
  146.     {"%sin", prim_1, double_sin},
  147.     {"%cos", prim_1, double_cos},
  148.     {"%atan2", prim_2, double_atan2},
  149.     {"%binary-logand", prim_2, binary_logand},
  150.     {"%binary-logior", prim_2, binary_logior},
  151.     {"%floor", prim_1, floor_func},
  152.     {"%ceiling", prim_1, ceiling},
  153.     {"%round", prim_1, round},
  154.     {"%truncate", prim_1, truncate},
  155.     {"%modulo", prim_2, modulo},
  156.     {"%modulo-double", prim_2, modulo_double},
  157.     {"%remainder-double", prim_2, remainder_double},
  158.     {"%remainder-int", prim_2, remainder_int},
  159.     {"%exp", prim_1, double_exp},
  160.     {"%ln", prim_1, double_log},
  161.     {"%floor/", prim_2, floor_divide},
  162.     {"%ceiling/", prim_2, ceiling_divide},
  163.     {"%round/", prim_2, round_divide},
  164.     {"%truncate/", prim_2, truncate_divide},
  165.     {"%int-truncate/", prim_2, int_truncate_divide},
  166. };
  167.  
  168. /* function definitions */
  169.  
  170. void
  171. init_number_prims (void)
  172. {
  173.     int num;
  174.  
  175.     num = sizeof (number_prims) / sizeof (struct primitive);
  176.  
  177.     init_prims (num, number_prims);
  178.  
  179. #ifdef BIG_INTEGERS
  180.     init_big_integer_prims ();
  181. #endif
  182. }
  183.  
  184. #ifdef BIG_INTEGERS
  185.  
  186. Object
  187. make_integer (int i)
  188. {
  189. #ifndef SMALL_OBJECTS
  190.     if (INT_ABS (i) <= MAX_SMALL_INT) {
  191.     Object obj;
  192.  
  193.     obj = allocate_object (sizeof (struct object));
  194.  
  195.     TYPE (obj) = Integer;
  196.     INTVAL (obj) = i;
  197.     return (obj);
  198.     } else
  199.     return make_big_integer (i);
  200. #else
  201.     if (INT_ABS (i) <= MAX_SMALL_INT)
  202.     return (MAKE_INT (i));
  203.     else
  204.     return make_big_integer (i);
  205. #endif
  206. }
  207.  
  208. #else
  209.  
  210. Object
  211. make_integer (int i)
  212. {
  213. #ifndef SMALL_OBJECTS
  214.     Object obj;
  215.  
  216.     obj = allocate_object (sizeof (struct object));
  217.  
  218.     TYPE (obj) = Integer;
  219.     INTVAL (obj) = i;
  220.     return (obj);
  221. #else
  222.     return (MAKE_INT (i));
  223. #endif
  224. }
  225. #endif
  226.  
  227. Object
  228. make_ratio (int numerator, int denominator)
  229. {
  230.     Object obj;
  231.  
  232.     obj = allocate_object (sizeof (struct ratio));
  233.  
  234.     RATIOTYPE (obj) = Ratio;
  235.     RATIONUM (obj) = numerator;
  236.     RATIODEN (obj) = denominator;
  237.     return (obj);
  238. }
  239.  
  240. Object
  241. make_dfloat (double d)
  242. {
  243.     Object obj;
  244.  
  245.     obj = allocate_object (sizeof (struct double_float));
  246.  
  247.     DFLOATTYPE (obj) = DoubleFloat;
  248.     DFLOATVAL (obj) = d;
  249.     return (obj);
  250. }
  251.  
  252. /* primitives */
  253.  
  254. static Object
  255. odd_p (Object n)
  256. {
  257.     if ((INTVAL (n) % 2) == 1) {
  258.     return (true_object);
  259.     } else {
  260.     return (false_object);
  261.     }
  262. }
  263.  
  264. static Object
  265. even_p (Object n)
  266. {
  267.     if ((INTVAL (n) % 2) == 0) {
  268.     return (true_object);
  269.     } else {
  270.     return (false_object);
  271.     }
  272. }
  273.  
  274. static Object
  275. int_zero_p (Object n)
  276. {
  277.     if (INTVAL (n) == 0) {
  278.     return (true_object);
  279.     } else {
  280.     return (false_object);
  281.     }
  282. }
  283.  
  284. static Object
  285. double_zero_p (Object n)
  286. {
  287.     if (DFLOATVAL (n) == 0.0) {
  288.     return (true_object);
  289.     } else {
  290.     return (false_object);
  291.     }
  292. }
  293.  
  294. static Object
  295. int_positive_p (Object n)
  296. {
  297.     if (INTVAL (n) > 0) {
  298.     return (true_object);
  299.     } else {
  300.     return (false_object);
  301.     }
  302. }
  303.  
  304. static Object
  305. double_positive_p (Object n)
  306. {
  307.     if (DFLOATVAL (n) > 0.0) {
  308.     return (true_object);
  309.     } else {
  310.     return (false_object);
  311.     }
  312. }
  313.  
  314. static Object
  315. int_negative_p (Object n)
  316. {
  317.     if (INTVAL (n) < 0) {
  318.     return (true_object);
  319.     } else {
  320.     return (false_object);
  321.     }
  322. }
  323.  
  324. static Object
  325. double_negative_p (Object n)
  326. {
  327.     if (DFLOATVAL (n) < 0.0) {
  328.     return (true_object);
  329.     } else {
  330.     return (false_object);
  331.     }
  332. }
  333.  
  334. static Object
  335. integral_p (Object n)
  336. {
  337.     if (INTEGERP (n)) {
  338.     return (true_object);
  339.     } else {
  340.     return (false_object);
  341.     }
  342. }
  343.  
  344. static Object
  345. int_to_double (Object n)
  346. {
  347.     return (make_dfloat (INTVAL (n)));
  348. }
  349.  
  350. static Object
  351. double_to_int (Object n)
  352. {
  353.     return (make_integer (DFLOATVAL (n)));
  354. }
  355.  
  356. static Object
  357. int_negative (Object n)
  358. {
  359.     return (make_integer (-INTVAL (n)));
  360. }
  361.  
  362. static Object
  363. double_negative (Object n)
  364. {
  365.     return (make_dfloat (-DFLOATVAL (n)));
  366. }
  367.  
  368. static Object
  369. int_inverse (Object n)
  370. {
  371.     return (make_dfloat (1.0 / INTVAL (n)));
  372. }
  373.  
  374. static Object
  375. double_inverse (Object n)
  376. {
  377.     return (make_dfloat (1 / DFLOATVAL (n)));
  378. }
  379.  
  380. static Object
  381. binary_int_plus (Object n1, Object n2)
  382. {
  383.     return (make_integer (INTVAL (n1) + INTVAL (n2)));
  384. }
  385.  
  386. static Object
  387. binary_int_minus (Object n1, Object n2)
  388. {
  389.     return (make_integer (INTVAL (n1) - INTVAL (n2)));
  390. }
  391.  
  392. #ifdef BIG_INTEGERS
  393.  
  394. static Object
  395. binary_int_times (Object n1, Object n2)
  396. {
  397.     int i1 = INTVAL (n1), i2 = INTVAL (n2);
  398.  
  399.     // watch for overflow.
  400.     if (i1 <= MAX_SMALL_FACTOR && i2 <= MAX_SMALL_FACTOR)
  401.     return make_integer (i1 * i2);
  402.     else
  403.     return binary_bigint_times (make_big_integer (i1), make_big_integer (i2));
  404. }
  405.  
  406. #else
  407.  
  408. static Object
  409. binary_int_times (Object n1, Object n2)
  410. {
  411.     return (make_integer (INTVAL (n1) * INTVAL (n2)));
  412. }
  413.  
  414. #endif
  415.  
  416. static Object
  417. binary_int_divide (Object n1, Object n2)
  418. {
  419.     if ((INTVAL (n1) % INTVAL (n2)) == 0) {
  420.     return (make_integer (INTVAL (n1) / INTVAL (n2)));
  421.     } else {
  422.     return (make_dfloat ((double) INTVAL (n1) / (double) INTVAL (n2)));
  423.     }
  424. }
  425.  
  426. static Object
  427. binary_double_plus (Object n1, Object n2)
  428. {
  429.     return (make_dfloat (DFLOATVAL (n1) + DFLOATVAL (n2)));
  430. }
  431.  
  432. static Object
  433. binary_double_minus (Object n1, Object n2)
  434. {
  435.     return (make_dfloat (DFLOATVAL (n1) - DFLOATVAL (n2)));
  436. }
  437.  
  438. static Object
  439. binary_double_times (Object n1, Object n2)
  440. {
  441.     return (make_dfloat (DFLOATVAL (n1) * DFLOATVAL (n2)));
  442. }
  443.  
  444. static Object
  445. binary_double_divide (Object n1, Object n2)
  446. {
  447.     return (make_dfloat (DFLOATVAL (n1) / DFLOATVAL (n2)));
  448. }
  449.  
  450. static Object
  451. binary_less_than (Object n1, Object n2)
  452. {
  453.     if (INTEGERP (n1)) {
  454.     if (INTEGERP (n2)) {
  455.         if (INTVAL (n1) < INTVAL (n2)) {
  456.         return (true_object);
  457.         } else {
  458.         return (false_object);
  459.         }
  460.     } else {
  461.         if (INTVAL (n1) < DFLOATVAL (n2)) {
  462.         return (true_object);
  463.         } else {
  464.         return (false_object);
  465.         }
  466.     }
  467.     } else {
  468.     if (INTEGERP (n2)) {
  469.         if (DFLOATVAL (n1) < INTVAL (n2)) {
  470.         return (true_object);
  471.         } else {
  472.         return (false_object);
  473.         }
  474.     } else {
  475.         if (DFLOATVAL (n1) < DFLOATVAL (n2)) {
  476.         return (true_object);
  477.         } else {
  478.         return (false_object);
  479.         }
  480.     }
  481.     }
  482. }
  483.  
  484. static Object
  485. int_sqrt (Object n)
  486. {
  487.     double ans;
  488.  
  489.     ans = sqrt (INTVAL (n));
  490.     if ((ans - floor (ans)) == 0) {
  491.     return (make_integer (ans));
  492.     } else {
  493.     return (make_dfloat (ans));
  494.     }
  495. }
  496.  
  497. static Object
  498. double_sqrt (Object n)
  499. {
  500.     return (make_dfloat (sqrt (DFLOATVAL (n))));
  501. }
  502.  
  503. static Object
  504. int_abs (Object n)
  505. {
  506.     int val;
  507.  
  508.     val = INTVAL (n);
  509.     if (val < 0) {
  510.     return (make_integer (-val));
  511.     } else {
  512.     return (n);
  513.     }
  514. }
  515.  
  516. static Object
  517. double_abs (Object n)
  518. {
  519.     return (make_dfloat (fabs (DFLOATVAL (n))));
  520. }
  521.  
  522. static Object
  523. int_quotient (Object n1, Object n2)
  524. {
  525.     return (make_integer (INTVAL (n1) / INTVAL (n2)));
  526. }
  527.  
  528. static Object
  529. ash (Object n, Object count)
  530. {
  531.     int num;
  532.  
  533.     num = INTVAL (count);
  534.     return (make_integer ((num > 0) ? (INTVAL (n) << num)
  535.               : (INTVAL (n) >> -num)));
  536. }
  537.  
  538. static Object
  539. double_sin (Object n1)
  540. {
  541.     return (make_dfloat (sin (DFLOATVAL (n1))));
  542. }
  543.  
  544. static Object
  545. double_cos (Object n1)
  546. {
  547.     return (make_dfloat (cos (DFLOATVAL (n1))));
  548. }
  549.  
  550. static Object
  551. double_atan2 (Object n1, Object n2)
  552. {
  553.     return (make_dfloat (atan2 (DFLOATVAL (n1), DFLOATVAL (n2))));
  554. }
  555.  
  556. static Object
  557. binary_logand (Object n1, Object n2)
  558. {
  559.     return (make_integer (INTVAL (n1) & INTVAL (n2)));
  560. }
  561.  
  562. static Object
  563. binary_logior (Object n1, Object n2)
  564. {
  565.     return (make_integer (INTVAL (n1) | INTVAL (n2)));
  566. }
  567.  
  568. static Object
  569. floor_func (Object d)
  570. {
  571.     double dval, tmp = floor (dval = DFLOATVAL (d));
  572.  
  573.     return construct_values (2,
  574.                  make_integer ((int) tmp),
  575.                  make_dfloat (dval - tmp));
  576. }
  577.  
  578. static Object
  579. ceiling (Object d)
  580. {
  581.     double dval, tmp = ceil (dval = DFLOATVAL (d));
  582.  
  583.     return construct_values (2,
  584.                  make_integer ((int) tmp),
  585.                  make_dfloat (dval - tmp));
  586. }
  587.  
  588. static Object
  589. round (Object d)
  590. {
  591.     double dval, tmp = anint (dval = DFLOATVAL (d));
  592.  
  593.     return construct_values (2,
  594.                  make_integer ((int) tmp),
  595.                  make_dfloat (dval - tmp));
  596. }
  597.  
  598. static Object
  599. truncate (Object d)
  600. {
  601.     double dval, tmp = aint (dval = DFLOATVAL (d));
  602.  
  603.     return construct_values (2,
  604.                  make_integer ((int) tmp),
  605.                  make_dfloat (dval - tmp));
  606. }
  607.  
  608. #if 0
  609. static int
  610. sign (int x)
  611. {
  612.     return (x < 0 ? -1 : (x > 0 ? 1 : 0));
  613. }
  614.  
  615. Object
  616. modulo (Object i1, Object i2)
  617. {
  618.     int i1val = INTVAL (i1);
  619.     int i2val = INTVAL (i2);
  620.     int q = (i1val / i2val);
  621.     int r = (i1val - i2val * q);
  622.  
  623.     if (r != 0) {
  624.     if (sign (i1val) != sign (i2val)) {
  625.         r += i2val;
  626.     }
  627.     }
  628.     return make_integer (r);
  629. }
  630.  
  631. #else
  632.  
  633. Object
  634. modulo (Object i1, Object i2)
  635. {
  636.     double d1val;
  637.     double d2val;
  638.     double tmp = (d1val = INTVAL (i1)) / (d2val = (float) INTVAL (i2));
  639.  
  640.     return make_integer ((int) (d1val - d2val * floor (tmp)));
  641. }
  642.  
  643. #endif
  644.  
  645. static Object
  646. modulo_double (Object d1, Object d2)
  647. {
  648.     double d1val;
  649.     double d2val;
  650.     double tmp = (d1val = DFLOATVAL (d1)) / (d2val = DFLOATVAL (d1));
  651.  
  652.     return make_dfloat (d1val - d2val * floor (tmp));
  653. }
  654.  
  655. static Object
  656. double_exp (Object n1)
  657. {
  658.     return (make_dfloat (exp (DFLOATVAL (n1))));
  659. }
  660.  
  661. static Object
  662. double_log (Object n1)
  663. {
  664.     return (make_dfloat (log (DFLOATVAL (n1))));
  665. }
  666.  
  667. static Object
  668. floor_divide (Object d1, Object d2)
  669. {
  670.     double d1val;
  671.     double d2val;
  672.     int intpart = floor ((d1val = DFLOATVAL (d1)) / (d2val = DFLOATVAL (d2)));
  673.  
  674.     return construct_values (2,
  675.                  make_integer (intpart),
  676.                  make_dfloat (d1val - d2val * intpart));
  677. }
  678.  
  679. static Object
  680. ceiling_divide (Object d1, Object d2)
  681. {
  682.     double d1val;
  683.     double d2val;
  684.     int intpart = ceil ((d1val = DFLOATVAL (d1)) / (d2val = DFLOATVAL (d2)));
  685.  
  686.     return construct_values (2,
  687.                  make_integer (intpart),
  688.                  make_dfloat (d1val - d2val * intpart));
  689. }
  690.  
  691. static Object
  692. round_divide (Object d1, Object d2)
  693. {
  694.     double d1val;
  695.     double d2val;
  696.     int intpart = anint ((d1val = DFLOATVAL (d1)) / (d2val = DFLOATVAL (d2)));
  697.  
  698.     return construct_values (2,
  699.                  make_integer (intpart),
  700.                  make_dfloat (d1val - d2val * intpart));
  701. }
  702.  
  703. static Object
  704. truncate_divide (Object d1, Object d2)
  705. {
  706.     double d1val;
  707.     double d2val;
  708.     int intpart = aint ((d1val = DFLOATVAL (d1)) / (d2val = DFLOATVAL (d2)));
  709.  
  710.     return construct_values (2,
  711.                  make_integer (intpart),
  712.                  make_dfloat (d1val - d2val * intpart));
  713. }
  714. static Object
  715. int_truncate_divide (Object i1, Object i2)
  716. {
  717.     int i1val;
  718.     int i2val;
  719.     int quotient = (int) ((float) (i1val = INTVAL (i1)) / (i2val = INTVAL (i2)));
  720.  
  721.     return construct_values (2,
  722.                  make_integer (quotient),
  723.                  make_integer (i1val - i2val * quotient));
  724. }
  725.  
  726. static Object
  727. remainder_double (Object d1, Object d2)
  728. {
  729.     double d1val;
  730.     double d2val;
  731.     int intpart = aint ((d1val = DFLOATVAL (d1)) / (d2val = DFLOATVAL (d2)));
  732.  
  733.     return make_dfloat (d1val - d2val * intpart);
  734. }
  735.  
  736. static Object
  737. remainder_int (Object i1, Object i2)
  738. {
  739.     int i1val;
  740.     int i2val;
  741.     int quotient = (int) ((float) (i1val = INTVAL (i1)) / (i2val = INTVAL (i2)));
  742.  
  743.     return make_integer (i1val - i2val * quotient);
  744. }
  745.  
  746. #ifdef NO_DOUBLE_INT_ARITH
  747. static double
  748. anint (double x)
  749. {
  750.     double y;
  751.  
  752.     if (x >= 0) {
  753.     return ((modf (x + 0.5, &y) < 0) ? (y - 1) : y);
  754.     } else {
  755.     return (-((modf (0.5 - x, &y) < 0) ? (y - 1) : y));
  756.     }
  757. }
  758.  
  759. static double
  760. aint (double x)
  761. {
  762.     double y;
  763.  
  764.     if (x > 0) {
  765.     return ((modf (x, &y) < 0) ? (y - 1) : y);
  766.     } else {
  767.     return (-((modf (-x, &y) < 0) ? (y - 1) : y));
  768.     }
  769. }
  770. #endif
  771.